<template>
  <div class="c-with-dialog">
    <div class="btn">
      <slot>
        <c-button v-if="showBtn" type="primary" @click="clickHandle">{{ btnText||title }}</c-button>
      </slot>
    </div>
    <el-dialog :visible.sync="visible" v-bind="$attrs" :show-close="false" :close-on-click-modal="false" @open="open" @opened="opened" @close="close" @closed="closed">
      <template #title>
        <div class="c-width-title-dialog">
          <div>{{ title }}</div>
          <div class="search">
            <el-select v-model="field" value-key="prop" style="width:150px;" @change="fieldCHange">
              <el-option v-for="item of columns.filter(e=>!!e.prop&&!e.hide)" :key="item.prop" :value="item" :label="item.label" />
            </el-select>
            <template v-if="field.propEnum">
              <c-dict-select v-model="searchValue" class="cDictSelect" style="width:150px;" :multiple="!!field.multiple" :dict-type-code="field.propEnum.dictTypeCode" :placeholder="field.label" />
            </template>
            <template v-else-if="field.searchType === 'date'">
              <el-date-picker
                v-model="searchValue"
                type="daterange"
                format="yyyy-MM-dd"
                value-format="yyyy-MM-dd HH:mm:ss"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                clearable
                style="width:150px;"
              />
            </template>
            <template v-else>
              <el-input v-model="searchValue" :placeholder="field.label" clearable />
            </template>
            <el-button type="primary" @click="searchClickHandle">搜索</el-button>
          </div>
        </div>
      </template>
      <slot name="header" />
      <Tabs
        ref="tabs"
        v-model="selections"
        :url="url"
        :columns="columns"
        :selection-columns="selectionColumns"
        :method="method"
        :filters-raw="comFiltersRaw"
        :params-raw="comParamsRaw"
        :multiple="multiple"
        :page-flag="pageFlag"
        :height="height"
      />
      <div class="btn-container">
        <slot name="btn" />
      </div>
    </el-dialog>
  </div>
</template>
<script>
import Tabs from './Tabs'
import { otherFiltersItem } from '@/utils'
export default {
  name: 'CWithDialog',
  components: {
    Tabs
  },
  props: {
    showBtn: {
      type: Boolean,
      default: true
    },
    btnText: {
      type: String,
      default: ''
    },
    title: {
      type: String,
      default: ''
    },
    openFun: {
      type: Function,
      default: undefined
    },
    vaule: {
      type: Array,
      default: () => []
    },
    filtersRaw: {
      type: Array,
      default: () => []
    },
    paramsRaw: {
      type: Object,
      default: () => ({})
    },
    pageFlag: {
      type: Boolean,
      default: true
    },
    url: {
      type: String,
      default: ''
    },
    method: {
      type: String,
      default: 'POST'
    },
    columns: {
      type: Array,
      default: () => []
    },
    selectionColumns: {
      type: Array,
      default: () => []
    },
    multiple: {
      type: Boolean,
      default: false
    },
    defaultField: {
      type: String,
      default: ''
    },
    height: {
      type: [String, Number],
      default: 400
    },
    searchMergeFiltersRaw: {
      type: Boolean,
      default: true
    },
    searchMergeParamsRaw: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      selections: [],
      visible: false,
      field: {},
      filtersRawDialog: [],
      paramsRawDialog: {},
      searchValue: '',
      mergeFiltersRaw: true,
      mergeParamsRaw: true
    }
  },
  computed: {
    comFiltersRaw() {
      if (this.mergeFiltersRaw) {
        return [...this.filtersRaw, ...this.filtersRawDialog]
      }
      return this.filtersRawDialog
    },
    comParamsRaw() {
      if (this.mergeParamsRaw) {
        return { ...this.paramsRaw, ...this.paramsRawDialog }
      }
      return this.paramsRawDialog
    }
  },
  watch: {
    selections(v) {
      this.$emit('input', v)
    }
  },
  created() {
    if (this.defaultField) {
      for (const item of this.columns) {
        if (item.prop === this.defaultField) {
          this.field = item
        }
      }
    } else if (this.columns.length > 0) {
      this.field = this.columns[0]
    }
  },
  activated() {
    const modal = document.querySelector('.v-modal')
    if (modal) {
      modal.style.display = 'block'
    }
  },
  deactivated() {
    this.$nextTick(() => {
      const modal = document.querySelector('.v-modal')
      if (modal) {
        modal.style.display = 'none'
      }
    })
  },
  methods: {
    open() {
      if (this.$listeners.open) {
        this.$listeners.open()
      }
    },
    opened() {
      window.addEventListener('keyup', this.enterHandle)
      this.$refs.tabs.searchGetData()
      if (this.$listeners.opened) {
        this.$listeners.opened()
      }
    },
    close() {
      this.$refs.tabs.data = []
      this.$refs.tabs.selections = []
      this.$refs.tabs.finished = false
      this.$refs.tabs.loading = false
      this.searchValue = ''
      this.filtersRawDialog = []
      this.paramsRawDialog = {}
      if (this.$listeners.close) {
        this.$listeners.close()
      }
    },
    closed() {
      window.removeEventListener('keyup', this.enterHandle)
      if (this.$listeners.closed) {
        this.$listeners.closed()
      }
    },
    enterHandle(e) {
      e.stopPropagation()
      e.preventDefault()
      if (e.keyCode === 13) {
        this.searchClickHandle()
      }
    },
    clickHandle() {
      let t = true
      if (this.openFun instanceof Function) {
        t = this.openFun()
      }
      if (!(t instanceof Promise)) {
        if (t) {
          t = Promise.resolve(t)
        } else {
          t = Promise.reject(t)
        }
      }
      return t.then(r => {
        this.visible = true
      })
    },
    fieldCHange() {
      this.searchValue = ''
    },
    searchClickHandle() {
      const f = this.field
      if (Object.keys(f).length === 0) return
      this.mergeFiltersRaw = this.searchMergeFiltersRaw
      this.mergeParamsRaw = this.searchMergeParamsRaw
      this.filtersRawDialog = []
      this.paramsRawDialog = {}
      const isNone = this.searchValue === '' || this.searchValue === undefined || this.searchValue === null || (this.searchValue instanceof Array && this.searchValue.length === 0)
      const type = f.searchField || 'filtersRaw'
      if (!isNone) {
        if (type === 'filtersRaw') {
          if (f.multiple) {
            this.filtersRawDialog = [otherFiltersItem(f.prop, `[${JSON.stringify(this.searchValue)}]`, f.operator || 'in')]
          } else if (f.searchType === 'date') {
            this.filtersRawDialog = [
              otherFiltersItem(f.prop, this.searchValue[0], '>='),
              otherFiltersItem(f.prop, this.searchValue[1], '<=')
            ]
          } else {
            let operator = f.operator || 'like'
            if (f.propEnum) {
              operator = '='
            }
            this.filtersRawDialog = [otherFiltersItem(f.prop, this.searchValue, operator)]
          }
        } else {
          if (f.multiple) {
            this.paramsRawDialog = { [f.prop]: this.searchValue.join(',') }
          } else {
            this.paramsRawDialog = { [f.prop]: this.searchValue }
          }
        }
      }
      this.$nextTick(() => {
        this.$refs.tabs.searchGetData().finally(() => {
          this.mergeFiltersRaw = true
          this.mergeParamsRaw = true
        })
      })
    }
  }
}
</script>
<style lang="scss" scoped>
.c-with-dialog{
  display: inline-block;
  .btn{

  }
  .c-width-title-dialog{
    display: flex;
    justify-content: space-between;
    align-items: center;
    .search{
      display: flex;
      justify-content: flex-end;
      align-items: center;
      &>:first-child{
        flex: 0 0 100px;
      }
      &>:nth-child(2){
        flex: 0 0 200px;
      }
      /deep/ input{
        border-right: none;
      }
      /deep/ input,.el-button{
        border-radius: 0px !important;
      }
      /deep/ .el-select input{
        border-top-left-radius: 4px !important;
        border-bottom-left-radius: 4px !important;
      }
      /deep/ .cDictSelect input{
        border-radius: 0 !important;
      }
      /deep/ .el-button{
        border-top-right-radius: 4px !important;
        border-bottom-right-radius: 4px !important;
      }
      /deep/ .el-date-editor{
        border-radius: 0 !important;
      }
    }
  }
}
</style>
